<!DOCTYPE html>
<html>

  <head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <title>雕虫晓技(八) Android与数据流的斗争</title>
  <meta name="description" content="Android与数据流的斗争。">
  <meta name="author" content="GcsSloop">
  <meta name="keywords" content="Android, rxjava, livedata, stream">
  <meta name="关键字" content="Android, rxjava, livedata, stream">
  

  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="雕虫晓技(八) Android与数据流的斗争">
  <meta name="twitter:description" content="Android与数据流的斗争。">
  <meta name="twitter:keywords" content="Android, rxjava, livedata, stream">
  
  <meta property="og:type" content="article">
  <meta property="og:title" content="雕虫晓技(八) Android与数据流的斗争">
  <meta property="og:description" content="Android与数据流的斗争。">
  <meta name="og:keywords" content="Android, rxjava, livedata, stream">

  <meta name="theme-color" content="#343434">
  
  <link rel="icon" type="image/png" href="https://raw.githubusercontent.com/GcsSloop/gcssloop.github.io/master/assets/siteinfo/favicon.png" />
  <link href="https://raw.githubusercontent.com/GcsSloop/gcssloop.github.io/master/assets/siteinfo/favicon.png" rel="shortcut icon" type="image/png">
  
  <link href="//netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet">
  <link rel="stylesheet" href="/css/main.css">

  <link rel="canonical" href="http://www.gcssloop.com/gebug/android-stream">
  <link rel="alternate" type="application/rss+xml" title="GcsSloop" href="http://www.gcssloop.com/feed.xml">
  
  <meta name="google-site-verification" content="Z_g58PkzRAyBMxkqrcDdWrTBK8oOWM-7rUHauhLNF2E" />
  <meta name="baidu-site-verification" content="kUtTXCKaZs" />
  <meta name="baidu-site-verification" content="6DuDv3aaJX" />
  
  <!--阅读次数统计-->
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"> </script>
  
  <!--Fuck Weixin and Baidu-->
  <meta http-equiv="Cache-Control" content="no-transform">
  <meta http-equiv=”Cache-Control” content=”no-siteapp” />
  <meta name="applicable-device" content="pc,mobile">
  <meta name="HandheldFriendly" content="true"/>

  <!-- Google Ad -->
  <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
  <script>
    (adsbygoogle = window.adsbygoogle || []).push({
      google_ad_client: "ca-pub-2767831356529421",
      enable_page_level_ads: true
    });
  </script>

</head>


  <body>

    <span class="mobile btn-mobile-menu">
        <i class="fa fa-list btn-mobile-menu__icon"></i>
        <i class="fa fa-angle-up btn-mobile-close__icon hidden"></i>
    </span>
    
    <header class="panel-cover panel-cover--collapsed" style="background-image: url('/assets/siteinfo/background-cover.jpg')">
  <div class="panel-main">

    <div class="panel-main__inner panel-inverted">
    <div class="panel-main__content">

        <a href="/#blog" title="前往 GcsSloop 的主页" class="blog-button"><img src="/assets/siteinfo/avatar.jpg" width="80" alt="GcsSloop logo" class="panel-cover__logo logo" /></a>
        <h1 class="panel-cover__title panel-title"><a href="/#blog" title="link to homepage for GcsSloop" class="blog-button">GcsSloop</a></h1>

        
        <span class="panel-cover__subtitle panel-subtitle">Just do IT later.</span>
        
        <hr class="panel-cover__divider" />
        <p class="panel-cover__description">嗨，我是 GcsSloop，一名来自2.5次元的魔法师，Android自定义View系列文章作者，非著名程序员。</p>
        <hr class="panel-cover__divider panel-cover__divider--secondary" />
        
        
        <p class="panel-cover__description">欢迎来到我的魔法世界!</p>
        
        
        <div class="navigation-wrapper">
          <div>
            <nav class="cover-navigation cover-navigation--primary">
              <ul class="navigation">
                <li class="navigation__item"><a href="/#blog" title="访问博客" class="blog-button">博客</a></li>
                
                  
                    <li class="navigation__item"><a href="https://github.com/GcsSloop" target="_blank" title="GcsSloop's GitHub">GitHub</a></li>
                  
                  
                
                  
                    <li class="navigation__item"><a href="/timeline" title="博客目录">目录</a></li>
                  
                  
                
                  
                    <li class="navigation__item"><a href="https://xiaozhuanlan.com/u/GcsSloop" target="_blank" title="小专栏">专栏</a></li>
                  
                  
                
                  
                    <li class="navigation__item"><a href="/category/customview" title="自定义View教程目录">自定义控件</a></li>
                  
                  
                
                  
                    <li class="navigation__item"><a href="/friends" title="友链">友链</a></li>
                  
                  
                
              </ul>
            </nav>
          </div>
          
          <div><nav class="cover-navigation navigation--social">
  <ul class="navigation">

  
  <!-- Weibo -->
  <li class="navigation__item">
    <a href="http://weibo.com/GcsSloop" title="@GcsSloop 的微博" target="_blank">
      <i class='social fa fa-weibo'></i>
      <span class="label">Weibo</span>
    </a>
  </li>
  

  
  <!-- Github -->
  <li class="navigation__item">
    <a href="https://github.com/GcsSloop" title="@GcsSloop 的 Github" target="_blank">
      <i class='social fa fa-github'></i>
      <span class="label">Github</span>
    </a>
  </li>
  
  
  
  <!-- Twitter -->
  <li class="navigation__item">
    <a href="http://twitter.com/GcsSloop" title="@GcsSloop" target="_blank">
      <i class='social fa fa-twitter'></i>
      <span class="label">Twitter</span>
    </a>
  </li>
  

    

  

  
  <!-- RSS -->
  <li class="navigation__item">
    <a href="/feed.xml" rel="author" title="RSS" target="_blank">
      <i class='social fa fa-rss'></i>
      <span class="label">RSS</span>
    </a>
  </li>
  

  
  <!-- Email -->
  <li class="navigation__item">
    <a href="mailto:GcsSloop@gmail.com" title="发邮件给我">
      <i class='social fa fa-envelope'></i>
      <span class="label">Email</span>
    </a>
  </li>
  

  
  <!-- Copyright -->
  <li class="navigation__item">
    <a href="http://choosealicense.online" title="选择版权"  target="_blank">
      <i class="social fa fa-copyright"></i>
      <span class="label">版权</span>
    </a>
  </li>
  
  
  </ul>
</nav>
</div>
        </div>
      </div>
    </div>
    
    
    <div class="panel-cover--overlay cover-slate"></div>
    
  </div>
</header>


    <div class="content-wrapper">
        <div class="content-wrapper__inner">
            <article class="post-container post-container--single" itemscope itemtype="http://schema.org/BlogPosting">
  <header class="post-header">
    <div class="post-meta" style="font-size:.8em">
      <time datetime="2018-08-12 00:00:00 +0800" itemprop="datePublished" class="post-meta__date date">2018-08-12</time> &#8226; <span class="post-meta__tags tags">Android</span> &#8226; View <span id="busuanzi_value_page_pv"></span> times.
</span>
    </div>
    <h1 class="post-title">雕虫晓技(八) Android与数据流的斗争</h1>
  </header>

  <section class="post">
    <h3 id="关于作者">关于作者</h3>

<p>GcsSloop，一名 2.5 次元魔法师。<br />
<a href="http://weibo.com/GcsSloop/home">微博</a> | <a href="https://github.com/GcsSloop">GitHub</a> | <a href="http://www.gcssloop.com/">博客</a></p>

<p><img src="http://gcsblog.oss-cn-shanghai.aliyuncs.com/blog/2019-04-29-073233.jpg?gcssloop" alt="" /></p>

<p>本文并没有什么实质性的内容，只是自己工作和学习这段时间的一些经验杂谈，仅从自己的角度阐述一下自己观察到的一些内容，可能并不全面，也不一定正确，仅供大家参考一下。</p>

<p>目前 Android 开发，从广义上来说可以划为前端的一部分，毕竟大部分 Android 开发所做的工作就是从服务器获取数据，将这些数据用合适的方式展示给用户，再把用户操作产生的数据传递给服务器。在这样的情境下 Android 开发所需要解决的一个核心问题就是数据的传递，如何把服务器与页面内容关联起来，并且保持同步。相信对于这一过程，每一个工程师都有自己的解决方案。这一个过程看似简单，但真正想要将其比较完美的实现，却也需要花费一番功夫。</p>

<h3 id="蛮荒时代">蛮荒时代</h3>

<p>在 Android 开发还未成熟，处于蛮荒时期的时候，没有成型方案作为参考，此时比较常见的做法就是在 Activity 里创建线程，在线程内发送网络请求，之后用 Handler 把请求结果传递到主线程，主线程收到信息后更新页面，这种方式缺陷是十分明显的，它会造成 Activity 十分臃肿，随着项目的发展会变成一团乱麻。</p>

<h3 id="网络库">网络库</h3>

<p>后来出现了诸多成型的网络的封装库，因此网络请求的核心逻辑就不在 Activity 中了，这为 Activity 减轻了不少负担，但是此时又一个问题出现了，那就是如何从请求库获取网络请求的返回结果，此时大多数网络库都采用了一个最容易想到的方案，那就是 Callback，Activity 发出请求时会得到一个 Callback，并通 Callback 回调得到最终的网络请求结果。</p>

<h3 id="数据层">数据层</h3>

<p>但是网络请求问题解决了，但是很快另一个问题又成了比较困扰的内容，例如：网络请求得到的结果并不能直接使用，需要进行一些数据的转换，又或者网络请求并不需太高的实时性，请求一次后需要缓存起来，避免多次重复请求。这样在 Activity 中就需要一些数据转换操作，或者进行一些数据库相关的操作，很快 Activity 又会变得臃肿起来。</p>

<p>为了避免在 Activity 中直接进行这些操作而变得臃肿，很多人不得不在网络请求和 Activity 之间封装一个数据层，Activity 向数据层请求数据，数据层根据需要从网络或者数据库获取数据并且对数据进行转换，然后交给 Activity。此时数据需要如何传递呢？</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Activity &lt;--callbac-1-- 数据层 &lt;--callback-2-- 网络请求
</code></pre>
</div>

<p>通常来说需要 Activity 向数据层发送请求时附带一个 Callback，而数据层直接向网络发出请求时又是另外一个 Callback，需要把数据从一个 Callback 传递到另一 Callback，当然这是对于一些比较简单的业务，如果业务更加复杂一点，可能会划分更多的层和节点，那么就不仅仅是两个 Callback 了，数据需要多在多个 Callback 之间流动，Callback 太多就会导致逻辑不是那么清晰，当项目大到一定程度时，里面的各种 Callback 就能把人绕晕。</p>

<h3 id="eventbus">EventBus</h3>

<p>为了解决错综复杂的 Callback 问题，EventBus 诞生了，它的核心其实就是发布订阅模式，当 Activity 需要获取一些信息时，发送一个事件(Event), 数据层接收到 Event 后执行相关操作，之后同样通过发送 Event 告诉 Activity 最终的结果。此时各个组件之间不需要再去关心各种错中复杂的数据传递方式，只需要把需要传递的数据包装成一个个的 Event 再通过 EventBus 发送出去，如果需要相关的事件的话，就在合适的位置注册一下监听该事件。</p>

<p><img src="/assets/gebug/08-android-stream/EventBus-Publish-Subscribe.png" alt="EventBus-Publish-Subscribe" /></p>

<p>所谓事件总线，就是把所有的事件都通过一个地方进行传递，这个和计算机硬件上的总线原理类似，因此也就被称为“事件总线”，在我最初接触到这种思想时，确实也被惊艳了一下，这种方式在一定程度上解决了过多 Callback 的问题，让代码看起来更加简洁了。</p>

<p>但是这种方式也并不是完美无缺的，<strong>它的确让代码更加简洁了，但是它将数据传递的过程隐藏起来了，相当于切断了数据流的追踪线路，增大了数据流追踪的难度</strong>，如果整个项目都是自己设计或者一开始就参与的问题倒是不大，但是如果是接手别人的项目是这样设计的，那么接手的人很可能会一脸懵逼。</p>

<p>例如：我需要当前的用户的信息，也知道通过哪个 Event 来接收这一信息，但是我发现接收到的信息有时是错误的，因此我需要找到发送该信息的位置并修改这一错误，这时就比较麻烦了，因为所有信息都是通过 EventBus 发送的，但我无法通过 EventBus 直接追踪到发送位置，因此我需要找到该 Event ，并追踪这个 Event 都被哪些地方使用了，然后从这些地方中筛选出时哪里发送了这个错误信息，对于一个庞大的项目来说，这一工作量无疑是巨大的，假若前人在多个地方都发送了这一个 Event，我则需要对所有发送过这个 Event 的地方都进行检查，这会浪费大量的工作时间。因此在实际的公司项目上我很少采用 EventBus 这一方案，尽管它很好用，但是这一点缺陷就足以致命。</p>

<h3 id="数据流">数据流</h3>

<p>正在我纠结到底如何传递数据时，Rx 技术方案就出现在了我的面前，Rx 的核心思想就是响应式编程，即<strong>一种面向数据流和变化传播的编程范式，数据更新是相关联的。</strong> 这种思想和 Linux 中的管道也是类似的，数据从一个地方进入转换后输出，而这个输出恰好是另一段处理的输入，就这样把数据串联起来。</p>

<p><img src="/assets/gebug/08-android-stream/DataTransform.jpg" alt="DataTransform" /></p>

<blockquote>
  <p>这是一个简单的例子，将一个空白的圆通过两步转换变成我们所需要的样子，数据从一个位置流向另一个位置，并不断的变化。<br />
Rx 核心之一就是数据流，包括 Java8 中也有引入类似的流式思想。</p>
</blockquote>

<p>响应式这一思想并不算特别新颖，不过是这种思想近些年才被人用代码实现出来具备了商用能力而已，随着 RxJava 技术的成熟，目前我参与的项目中所有的数据获取基本都是通过 RxJava 进行处理的。并且基于 RxJava 提供的强大操作符和线程调度能力，确实也算解决了一大难题。</p>

<p>相比于 EventBus 这种形式，这种方案最重要的还是数据流的可追踪性，还是上面的例子，如果我发现了最终的结果有错误，那么我只需要跟随着这条数据链不断的向上追踪，并逐一环节的进行检查即可，很快就能找到问题的根源所在。就目前而言，这种方式还是不错的，尤其是配合 Java8 的一些新特性使用，相当爽快。</p>

<p><strong>如果想要了解这一思想的运用方式，个人推荐看 《RxJava的官方文档》和 《Java8 实战》，看完这些基本就可以理解响应式编程中数据流这一思想了。</strong></p>

<h3 id="livedata">LiveData</h3>

<p><strong>LiveData 是 Google 最近推出的一种技术方案，它需要配合 Lifecycle 来使用，它解决的问题核心不是数据传输的问题，而是生命周期。</strong>我们都知道网络传输是比较慢的，而且具有不确定性，因此 Android 不允许其在主线程中执行，必须另开线程，在线程中获得结果后通过一些方式将结果告诉主线程，主线程并根据这些信息进行更新，正是因为网络返回时间的不确定性导致了一个问题的发生，当网络结果返回时，可能需要这一结果的页面已经不存在了。</p>

<p>例如：在我打开一个 activity 时发起了一个网络，网络请求的结果会更新 activity 里面的内容，但是在我发起请求后我不想要这个结果了，直接点击返回键把 activity 关闭了，如果我在关闭 activity 时忘记了取消这次网络请求，那么它在一段时间后就可能会返回结果，并在返回结果里面尝试去更新一些已经被销毁的 View，就会产生异常，导致程序崩溃。</p>

<p>为了避免这些问题的出现我们不得不在代码里面添加很多安全检查，每当有类似的情况出现都需要安全检查，于是核心的业务逻辑就可能被淹没在了诸多的安全检查中。</p>

<p>为了解决这一问题，Lifecycle 和 LiveData 就出现了，其实在 Lifecycle 出现之前，就有采用类似思想的技术方案出现，但是 Lifecycle 是 Google 官方推出的内容，在 support 包里面的很多组件已经默认支持了 Lifecycle，因此使用 Lifecycle 和 LiveData 会更加的简便。</p>

<p>在引入的 LiveData 后，基本的项目结构就变成下面这样了：</p>

<p><img src="/assets/gebug/08-android-stream/BasicStructure.jpg" alt="BasicStructure" /></p>

<blockquote>
  <p>这只是一个简略的结构，在实际的项目中使用时肯定是比这个要复杂的，需要根据具体的业务需求选择不同的技术方案。</p>
</blockquote>

<p>在经过上述的几次演变后，Activity 的工作量大大的减轻了，网络、数据库、一部分安全检查逻辑都被从 Activity 中移除了，Activity 只需要绑定一下 View，并控制一下显示内容就可以了，因此会看起来特别的简洁，如果配合 Butterknife 和 Dagger2 来使用的话，会更加简洁，不过这两个内容并不在本文的讨论范围内，因此也就不展开叙述了。</p>

<p>以上提到的相关技术，并没有详细的说明，若比较感兴趣，可以自己查询关键词去详细的了解一下。</p>

<h3 id="结语">结语</h3>

<p>马上结束了，顺便插一个题外话，随着 Android 相关从业人员的大量增加，相关的技术发展也是突飞猛进，几乎每个一段时间都有新的技术跳到我们面前，例如近两年蓬勃发展的 MVP 和 MVVM 架构，Kotlin，Flutter 等技术，很多人感觉自己在被技术追着走一样，似乎一天不学习，明天就赶不上发展形势了。在这种情况下，有些人被逼不断的去学习这些新技术，不断的储备，未雨绸缪。也有人在主动的追逐着这些新技术，每当新技术出现后，就迫不及待的想要把这些技术用到现有的项目中。</p>

<p>我个人觉得被迫学习或者疯狂追逐都不是一种很好的状态，每当一项新技术的出现，必然是解决了一些旧有技术无法解决的痛点，在新技术出现时没必要第一时刻就去学习如何使用它，但需要先查一下它的来龙去脉，它是为何而来，解决了哪些问题，相比于之前的技术有何优点，缺陷又在哪里。只有在了解了这些情况之后，再根据自身情况决定是否需要学习，盲目的学习可能会浪费掉自己的时间，同样，根据公司的项目需求再决定是否应该引入这项技术，有时引入一项不合适的技术方案反而会拖慢整体的进度。</p>

<p>最后，以上的一些观点仅为自己观察的内容，由于自己从业时间有限，接触到的项目自然也是有限的，所以上述理论并不能适合所有的 Android 项目，具体情况还需要具体分析才行。</p>

    <hr>
  </section>
</article>

<!--广告-->

<!--
<div>
<a href="https://m.aliyun.com/act/team1111/?spm=5176.11533457.1089570.5.424777e3AF8WOJ&userCode=hn5smxtw#/" target="_blank"><img src="/assets/aliyun/1111-980-120.jpg" width="100%"></a>
</div>
-->
<!--捐赠晶石-->
<section class="contribute">
    <script type="text/javascript"> 
      function toggle() {
        var con = document.getElementById("contribute");
        if (con.style.display == "none") {
          con.style.display = "block";
        } else {
          con.style.display = "none";
        }
      }
    </script> 
    <blockquote style="background-color:#F5F5F5; padding: 10px 20px 20px 10px; margin:0px" >
      <h4> 如果你觉得我的文章对你有帮助的话，欢迎赞助一些服务器费用! </h4>
      <p></p>
      <a id=“btn-toggle-contribute” class="btn-contribute" onclick="toggle()" >¥ 点击赞助</a>
      <br>
      <div id="contribute" style="display:none;">
        <p align="center" >
        <img src="/assets/images/wechat.png" alt="微信">
        <img src="/assets/images/alipay.png" alt="支付宝">
        </p>
        <p align="left" >
          <b>感谢所有支持我的魔法师，所有支持过我的魔法师都可以通过微信(GcsSloop)联系我，获赠我的付费专栏！</b>
          <!--
          <a href="/contribute">点击这里查看捐赠者名单。</a>
          -->
        </p>
      </div>
    </blockquote>
</section>
<div>
  <h2>欢迎关注我的微信公众号</h2>
  <img src="/assets/images/banner.jpg" width="100%">
</div>

<!--阅读更多-->
<section class="read-more">
  
  
  <div class="read-more-item">
    <span class="read-more-item-dim">最近的文章</span>
    <h2 class="post-list__post-title post-title"><a href="/gebug/netty-private-protocol" title="link to 雕虫晓技(九) Netty与私有协议框架">雕虫晓技(九) Netty与私有协议框架</a></h2>
    <p class="excerpt">关于作者GcsSloop，一名 2.5 次元魔法师。微博 | GitHub | 博客1.前言【本文示例源码下载】在本系列的前一篇，说了 Android 与数据流的斗争，主要是 Android 前...&hellip;</p>
    <div class="post-list__meta">
      <time datetime="2018-09-01 00:00:00 +0800" class="post-list__meta--date date">2018-09-01</time> &#8226; <span class="post-list__meta--tags tags">GeBug</span>
      <br/><br/>
      <a style="float:none; margin:0 auto;" class="btn-border-small" href=/gebug/netty-private-protocol>继续阅读</a></div>
   </div>
   
   
   
   
   <div class="read-more-item">
       <span class="read-more-item-dim">更早的文章</span>
       <h2 class="post-list__post-title post-title"><a href="/customview/scalegesturedetector" title="link to 安卓自定义View进阶-缩放手势检测(ScaleGestureDecetor)">安卓自定义View进阶-缩放手势检测(ScaleGestureDecetor)</a></h2>
       <p class="excerpt">0. 前言Android 缩放手势检测，ScaleGestureDetector 相关内容的用法和注意事项，本文依旧属于事件处理这一体系，在大多数的情况下，缩放手势都不是单独存在的，需要配合其它...&hellip;</p>
       <div class="post-list__meta">
          <time datetime="2018-08-09 00:00:00 +0800" class="post-list__meta--date date">2018-08-09</time> &#8226; <span class="post-list__meta--tags tags">CustomView</span>
          <br/><br/>
          <a style="float:none; margin:0 auto;" class="btn-border-small" href=/customview/scalegesturedetector>继续阅读</a>
       </div>
   </div>
   
</section>

<!--网易云跟帖-->
<!--
<div id="cloud-tie-wrapper" class="cloud-tie-wrapper"></div>
<script src="https://img1.cache.netease.com/f2e/tie/yun/sdk/loader.js"></script>
<script>
var cloudTieConfig = {
  url: document.location.href, 
  sourceId: "",
  productKey: "a85dba2840134721a7b69a15b2e0f217",
  target: "cloud-tie-wrapper"
};
var yunManualLoad = true;
Tie.loader("aHR0cHM6Ly9hcGkuZ2VudGllLjE2My5jb20vcGMvbGl2ZXNjcmlwdC5odG1s", true);
</script>
-->

<style type="text/css">
.isso-comment > div.avatar {
    border: 0px;
    box-shadow: none;
    display: block;
    float: left;
    width: 7%;
    margin: 3px 15px 0 0;
}
.isso-postbox > .form-wrapper > .auth-section .post-action > input {
    border-radius: 6px;
    padding: 6px;
    padding-left: 16px;
    padding-right: 16px;
    border: 1px solid #CCC;
    background-color: #D58D44;
    cursor: pointer;
    outline: 0;
    color: #fff;
    size: 10;
    line-height: 1.4em;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.isso-postbox > .form-wrapper > .auth-section .post-action > input:hover {
    background-color: #272822;
}
.isso-postbox > .form-wrapper > .auth-section .post-action > input:active {
    background-color: #986530;
}
</style>

<section id="isso-thread"></section>

<script data-isso="//47.52.58.34:1234/"
        data-isso-css="true"
        data-isso-lang="zh"
        data-isso-reply-to-self="false"
        data-isso-require-author="false"
        data-isso-require-email="false"
        data-isso-max-comments-top="10"
        data-isso-max-comments-nested="5"
        data-isso-reveal-on-click="5"
        data-isso-avatar="true"
        data-isso-avatar-bg="#f0f0f0"
        data-isso-avatar-fg="#9abf88 #5698c4 #e279a3 #9163b6 ..."
        data-isso-vote="true"
        data-vote-levels=""
        src="//47.52.58.34:1234/js/embed.min.js">
        </script>

<!--
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
-->
<!-- OneV's Den -->
<!--
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-3324997515191619"
     data-ad-slot="9170309685"
     data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
-->

            <section class="footer">
    <footer>
    	<span class="footer__copyright">本站点采用<a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh" target="_blank">知识共享 署名-非商业性使用-禁止演绎 4.0 国际 许可协议</a></span>
        <span class="footer__copyright">本站由 <a href="http://www.GcsSloop.com">@GcsSloop</a> 创建，采用 <a href="https://github.com/GcsSloop/Gcs-Vno-Jekyll" target="_blank">Gcs-Vno-Jekyll</a> 作为主题。<span id="busuanzi_container_site_pv"> 总访问量 <span id="busuanzi_value_site_pv"></span> 次</span> - &copy; 2019</span>
        <span class="footer__sitemap, footer__copyright"><a href="http://www.gcssloop.com/sitemap.xml" target="_blank">Site Map</a>
        <a href="http://www.gcssloop.com/vip" target="_blank">vip</a></span>
    </footer>
</section>

        </div>
    </div>
    
    <script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>

<script type="text/javascript" src="/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

<script type="text/javascript" src="/js/main.js"></script>

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-82493667-1', 'auto');
  ga('send', 'pageview');

</script>

    
  </body>

</html>
